package com.gs.common.tool.utils;

import com.google.common.collect.Lists;
import com.gs.common.tool.consts.UserConst;
import com.gs.common.tool.pojo.AnnotationInfo;
import com.gs.common.tool.pojo.ClassInfo;
import com.gs.common.tool.pojo.ColumnInfo;

import java.io.File;
import java.util.List;

public class JavaCodeGenUtil {


    /**
     * 根据数据库列信息，生成实体类
     *
     * @param filePath       实体类路径
     * @param scheme         模式名
     * @param tableName      表名
     * @param packageName    包路径
     * @param columnInfoList 列信息
     * @date 2024/05/17 15:54
     **/
    public static void genPojo(String filePath, String scheme, String tableName, String pojoName, String packageName, String enableTableSuper, String enableSuper, String superClass, String tableComment, List<ColumnInfo> columnInfoList, String author) {
        tableComment = tableComment + "实体类";
        //类名
        String clzName = String.format("%s.%s", packageName, pojoName);
        //文件全路径
        String file = String.format("%s%s%s", filePath, File.separator, clzName.replace(".", File.separator));
        boolean haveSuperClz = ClzUtil.isHaveSuperClass(enableTableSuper, enableSuper, superClass);
        //添加lombok导入
        List<String> thirdClzNameList = LombokUtil.addAnnotationFullName(haveSuperClz);
        //第三方类导入
        thirdClzNameList.addAll(Lists.newArrayList("com.baomidou.mybatisplus.annotation.*",
                "com.fasterxml.jackson.databind.annotation.JsonSerialize", "com.fasterxml.jackson.databind.ser.std.ToStringSerializer"));
        //注解集合
        List<AnnotationInfo> annotationList = LombokUtil.addAnnotationShortName(haveSuperClz);
        annotationList.add(new AnnotationInfo("TableName", Lists.newArrayList(new AnnotationInfo.Field(String.format("%s.%s", scheme, tableName)))));
        if (haveSuperClz) {
            columnInfoList.removeIf(c -> UserConst.ignoreFieldList.contains(c.getColumnName()));
        }
        FileUtil.writeToJavaFile(file, ClzUtil.genClass(annotationList, true, clzName, haveSuperClz ? new ClassInfo(superClass, null) : null, new ClassInfo("java.io.Serializable", null), tableComment, author, ClzUtil.addSerialVersionUID() + ClzUtil.addField(columnInfoList, thirdClzNameList), thirdClzNameList));
    }

    /**
     * 创建mapper
     *
     * @param filePath       文件路径
     * @param dbName         数据库名
     * @param entityFullName 实体类全包名
     * @param packageName    包名
     * @param tableComment   表注释
     * @param author         作者
     */
    public static void genMapper(String filePath, String dbName, String entityFullName, String packageName, String enableTableSuper, String enableSuper, String superClass, String tableComment, String classSuffix, String author) {
        tableComment = tableComment + "数据访问层";
        //类名
        String clzName = String.format("%s.%s%s", packageName, PoJoUtil.getShortName(entityFullName), classSuffix);
        //文件全路径
        String file = String.format("%s%s%s", filePath, File.separator, clzName.replace(".", File.separator));
        //第三方类导入
        List<String> thirdClzNameList = Lists.newArrayList();
        //注解集合
        List<AnnotationInfo> annotationList = Lists.newArrayList();
        //dbName不空，添加多数据源注解
        if (StringUtil.isNotEmpty(dbName)) {
            annotationList.add(new AnnotationInfo("DS", Lists.newArrayList(new AnnotationInfo.Field(String.format("%s", dbName), null))));
            thirdClzNameList.add("com.baomidou.dynamic.datasource.annotation.DS");
        }
        boolean haveSuperClass = ClzUtil.isHaveSuperClass(enableTableSuper, enableSuper, superClass);
        ClassInfo superClz = new ClassInfo(haveSuperClass ? superClass : "com.baomidou.mybatisplus.core.mapper.BaseMapper", Lists.newArrayList(entityFullName));
        FileUtil.writeToJavaFile(file, ClzUtil.genClass(annotationList, false, clzName, superClz, null, tableComment, author, null, thirdClzNameList));
    }


    /**
     * 创建Service
     *
     * @param filePath       文件路径
     * @param entityFullName 实体类全包名
     * @param packageName    包名
     * @param tableComment   表注释
     * @param author         作者
     */
    public static void genService(String filePath, String entityFullName, String packageName, String classSuffix, String enableTableSuper, String enableSuper, String superClass, String tableComment, String author) {
        tableComment = tableComment + "业务接口类";
        //类名
        String clzName = String.format("%s.I%s%s", packageName, PoJoUtil.getShortName(entityFullName), classSuffix);
        //文件全路径
        String file = String.format("%s%s%s", filePath, File.separator, clzName.replace(".", File.separator));
        boolean haveSuperClass = ClzUtil.isHaveSuperClass(enableTableSuper, enableSuper, superClass);
        ClassInfo superClz = new ClassInfo(haveSuperClass ? superClass : "com.baomidou.mybatisplus.extension.service.IService", Lists.newArrayList(entityFullName));
        FileUtil.writeToJavaFile(file, ClzUtil.genClass(null, false, clzName, superClz, null, tableComment, author, null, null));
    }


    /**
     * 创建Service
     *
     * @param filePath       文件路径
     * @param entityFullName 实体类全包名
     * @param packageName    包名
     * @param tableComment   表注释
     * @param author         作者
     */
    public static void genServiceImpl(String filePath, String entityFullName, String serviceFullName, String packageName, String classSuffix, String enableTableSuper, String enableSuper, String superClass, String tableComment, String author) {
        tableComment = tableComment + "业务实现类";
        //类名
        String clzName = String.format("%s.%s%s", packageName, PoJoUtil.getShortName(serviceFullName).substring(1), classSuffix);
        //文件全路径
        String file = String.format("%s%s%s", filePath, File.separator, clzName.replace(".", File.separator));
        //第三方类导入
        List<String> thirdClzNameList = Lists.newArrayList("org.springframework.stereotype.Service");
        //注解集合
        List<AnnotationInfo> annotationList = Lists.newArrayList();
        annotationList.add(new AnnotationInfo("Service", null));
        boolean haveSuperClass = ClzUtil.isHaveSuperClass(enableTableSuper, enableSuper, superClass);
        ClassInfo superClz = null;
        if (haveSuperClass) {
            superClz = new ClassInfo(superClass, Lists.newArrayList(entityFullName));
        }
        ClassInfo inter = new ClassInfo(serviceFullName, null);
        FileUtil.writeToJavaFile(file, ClzUtil.genClass(annotationList, true, clzName, superClz, inter, tableComment, author, null, thirdClzNameList));
    }


    /**
     * 创建Service
     *
     * @param filePath       文件路径
     * @param entityFullName 实体类全包名
     * @param packageName    包名
     * @param tableComment   表注释
     * @param author         作者
     */
    public static void genServiceImpl(String filePath, String dbName, String entityFullName, String mapperFullName, String serviceFullName, String packageName, String classSuffix, String enableTableSuper, String enableSuper, String superClass, String tableComment, String author) {
        tableComment = tableComment + "业务实现类";
        //类名
        String clzName = String.format("%s.%s%s", packageName, PoJoUtil.getShortName(serviceFullName).substring(1), classSuffix);
        //文件全路径
        String file = String.format("%s%s%s", filePath, File.separator, clzName.replace(".", File.separator));
        //第三方类导入
        List<String> thirdClzNameList = Lists.newArrayList("org.springframework.stereotype.Service");
        //注解集合
        List<AnnotationInfo> annotationList = Lists.newArrayList();
        annotationList.add(new AnnotationInfo("Service", null));
        //dbName不空，添加多数据源注解
        if (StringUtil.isNotEmpty(dbName)) {
            annotationList.add(new AnnotationInfo("DS", Lists.newArrayList(new AnnotationInfo.Field(String.format("%s", dbName), null))));
            thirdClzNameList.add("com.baomidou.dynamic.datasource.annotation.DS");
        }
        boolean haveSuperClass = ClzUtil.isHaveSuperClass(enableTableSuper, enableSuper, superClass);
        ClassInfo superClz = new ClassInfo(haveSuperClass ? superClass : "com.baomidou.mybatisplus.extension.service.impl.ServiceImpl", Lists.newArrayList(mapperFullName, entityFullName));
        ClassInfo inter = new ClassInfo(serviceFullName, null);
        FileUtil.writeToJavaFile(file, ClzUtil.genClass(annotationList, true, clzName, superClz, inter, tableComment, author, null, thirdClzNameList));
    }


    /**
     * 创建Controller
     *
     * @param filePath        文件路径
     * @param serviceFullName service类全包名
     * @param entityFullName  实体类全包名
     * @param packageName     包名
     * @param tableComment    表注释
     * @param author          作者
     */
    public static void genController(String filePath, String entityFullName, String serviceFullName, String packageName, String classSuffix, String enableTableSuper, String enableSuper, String superClass, String tableComment, String author) {
        tableComment = tableComment + "api";
        //类名
        String clzName = String.format("%s.%s%s", packageName, PoJoUtil.getShortName(entityFullName), classSuffix);
        //文件全路径
        String file = String.format("%s%s%s", filePath, File.separator, clzName.replace(".", File.separator));
        //第三方类导入
        List<String> thirdClzNameList = Lists.newArrayList("org.springframework.web.bind.annotation.RestController", "org.springframework.web.bind.annotation.RequestMapping");
        //注解集合
        List<AnnotationInfo> annotationList = Lists.newArrayList();
        annotationList.add(new AnnotationInfo("RestController", null));
        annotationList.add(new AnnotationInfo("RequestMapping", Lists.newArrayList(new AnnotationInfo.Field(String.format("/%s", PoJoUtil.firstToLower(PoJoUtil.getShortName(entityFullName)))))));
        boolean haveSuperClass = ClzUtil.isHaveSuperClass(enableTableSuper, enableSuper, superClass);
        //类body
        String content = null;
        //父类
        ClassInfo superClz = null;
        if (haveSuperClass) {
            superClz = new ClassInfo(superClass, Lists.newArrayList(serviceFullName, entityFullName));
        } else {
            content = ClzUtil.addAutoField(serviceFullName);
            thirdClzNameList.add(serviceFullName);
            thirdClzNameList.add("org.springframework.beans.factory.annotation.Autowired");
        }
        FileUtil.writeToJavaFile(file, ClzUtil.genClass(annotationList, true, clzName, superClz, null, tableComment, author, content, thirdClzNameList));
    }
}